//
// GPSMapEdit
// (c) Konstantin Galichsky (kg@geopainting.com), 2003-2007
// ALAN and ALAN Map 500 are registered trademarks of ALAN Group.
//
// ALAN Map 500 WRT (legacy) waypoints export.
//

# include "StdAfx.h"
# include "HoluxWrt.h"
# include "Save.h"
# include "Map.h"
# include "Status.h"
# include "SaveFileDlg.h"
# include "FileWriter.h"
# include "fast_floor.h"
# include "Globals.h"

class CAlanWrtExport : public CMapSaver {
  public:
	virtual bool CanSave (const map_t & _map) {return true;}
	virtual bool Save (HANDLE _hFile, const char * _strFileName, const map_t & _map);

  private:
	bool _Save (HANDLE _hFile, const map_t & _map);
};

//DECLARE_WPTRK_EXPORT (CAlanWrtExport, "alan-wrt", "wrt", "ALAN Map 500 legacy waypoints (*.wrt)");

bool CAlanWrtExport::Save (HANDLE _hFile, const char * _strFileName, const map_t & _map) {
	if (_hFile) {
		return _Save (_hFile, _map);
	} else {
		//
		// Prepare default file name.
		//
		char strFileName [MAX_PATH + 1];
		::strncpy (strFileName, _strFileName, MAX_PATH);
		strFileName [MAX_PATH] = '\0';
		if (! SaveFileDlg ("wrt", "ALAN Map 500 waypoints (*.wrt)\0*.wrt\0", strFileName))
			return false;

		//
		// Open the file.
		//
		const CFileForWrite hFile (strFileName);
		if (! hFile.IsValid ()) {
			ErrorMsgBox ("Can't create file:\n %s", strFileName);
			return false;
		}

		return _Save (hFile, _map);
	}
}

bool CAlanWrtExport::_Save (HANDLE _hFile, const map_t & _map) {
	// Get time zone shift.
	TIME_ZONE_INFORMATION tzi;
	if (::GetTimeZoneInformation (& tzi) == TIME_ZONE_ID_DAYLIGHT)
		tzi.Bias += tzi.DaylightBias;
	const double dtTimeShift = float (tzi.Bias)/(24*60);

	SYSTEMTIME stCurrentTime;
	::GetLocalTime (& stCurrentTime);

	SetProgressStatus (0);

	//
	// Prepare the file content.
	//
	CWrtFile wrt;
	::memset (& wrt, 0, sizeof (wrt));

	// Prepare waypoints header.
	wrt.WptHdr.dwSignature = c_dwWrtWptSignature;
	::memset (& wrt.WptHdr.wIdx, 0xFF, sizeof (wrt.WptHdr.wIdx));

	size_t cOrdinal = 0;

	size_t cRgn = 0;
	const size_t cRgns = _map.GetRgnCount ();
	for (size_t cKind = 0; cKind < rkMax; ++ cKind) {
		const layer_t & layer = _map.layers [cKind];
		const rgns_t & rgns = layer.rgns;
		for (rgns_t::const_iterator iRgn = rgns.begin (); iRgn != rgns.end (); ++ iRgn, ++ cRgn) {
			const rgn_t & rgn = * iRgn;
			if (rgn.IsDeleted () || ! rgn.IsWaypoint ())
				continue;

			const waypoint_info_t * const pWptExtra = rgn.pExtra ? rgn.pExtra->wtr.wpt () : NULL;

			// Save waypoint.
			for (size_t cOrigin = 0; cOrigin < rgn.origins.size (); ++ cOrigin) {
				const rgn_origin_t & origin = rgn.origins [cOrigin];
				if (origin.bDeleted)
					continue;

				if (cOrdinal >= c_cWrtMaxWaypoints)
					break;
				CWrtWaypoint & wpt = wrt.Waypoints [cOrdinal];

				// Name.
				::memset (& wpt.strName, ' ', sizeof (wpt.strName));
				::strncpy (wpt.strName,    rgn.strLabel.c_str (),   rgn.strLabel.size ()   < sizeof (wpt.strName)    ? rgn.strLabel.size   () : sizeof (wpt.strName));

				// Comment.
				::memset (& wpt.strComment, ' ', sizeof (wpt.strComment));
				::strncpy (wpt.strComment, rgn.strComment.c_str (), rgn.strComment.size () < sizeof (wpt.strComment) ? rgn.strComment.size () : sizeof (wpt.strComment));

				// Position.
				wpt.lX =  fast_floor (origin.point.x*36000 + .5f);
				wpt.lY = -fast_floor (origin.point.y*36000 + .5f);

				// Date and time.
				SYSTEMTIME st;
				if (pWptExtra && (pWptExtra->wFlags & waypoint_info_t::defTime))
					::VariantTimeToSystemTime (pWptExtra->dtTime - dtTimeShift, & st);
				else
					st = stCurrentTime;
				wpt.dwDate = st.wDay + (st.wMonth << 8) + (st.wYear << 16);
				wpt.dwTime = st.wSecond + st.wMinute*60 + st.wHour*60*60;

				// Show.
				wpt.btActive = pWptExtra && pWptExtra->GetShow () != waypoint_info_t::showHide ? 1 : 0;

				wpt.wRoutesRefs = 0;

				wrt.WptHdr.btUsed [cOrdinal] = 0xFF;
				wrt.WptHdr.wIdx [cOrdinal] = cOrdinal;

				++ cOrdinal;
			}

			SetProgressStatus (fast_floor (100.f*cRgn/cRgns + .5f));
		}
	}

	wrt.WptHdr.wCurrentWaypoints = cOrdinal;
	wrt.WptHdr.wNextWaypoints = cOrdinal;

	// Prepare header of routes (empty).
	::memset (& wrt.RoutesHdr, 0, sizeof (wrt.RoutesHdr));
	wrt.RoutesHdr.wNextRoutes = 1;
	wrt.RoutesHdr.dwSignature = c_dwWrtRoutesSignature;
	::memset (& wrt.RoutesHdr.wIdx, 0xFF, sizeof (wrt.RoutesHdr.wIdx));
	wrt.RoutesHdr.wNavigationRoute = 0xFFFF;

	::memset (& wrt.unused, 0xFF, sizeof (wrt.unused));

	if (cOrdinal >= c_cWrtMaxWaypoints)
		WarningMsgBox ("Only first 500 waypoints are saved.\n(NOTE:this is the WRT format limitation).");

	//
	// Write the file.
	//
	CFileWriter fw (_hFile);
	fw.WriteBin (wrt);
	fw.FlushBuffer ();

	SetProgressStatus (100);

	return true;
}
